#include <cstdlib>
#include <exception>

using namespace std;

// 这些版本可能抛出异常
// void *operator new(size_t);                          // 分配一个对象
// void *operator new[](size_t);                        // 分配一个数组
// void *operator delete(void*) noexcept;               // 释放一个对象
// void *operator delete[](void*) noexcept;             // 释放一个数组

// 这些版本承诺不会抛出异常
// void *operator new(size_t, nothrow_t&) noexcept;
// void *operator new[](size_t, nothrow_t&) noexcept;
// void *operator delete(void*, nothrow_t&) noexcept;
// void *operator delete[](void*, nothrow_t&) noexcept;

// void *operator new(size_t, void*);   // 不允许用户重载这个版本

/**
 * 用户重载的是 operator new/delete 函数，而不是 new/delete 表达式
 * new/delete 表达式无法被用户重载
 * new 表达式总是先调用 operator new 函数以获取内存空间，然后构造对象
 * delete 表达式总是先销毁对象，然后调用 operator delete 函数释放内存空间
 */

void *operator new(size_t size) {
    if (void *mem = malloc(size))
        return mem;
    else
        throw bad_alloc();
}

void operator delete(void *mem) noexcept { free(mem); }